﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.IO;

namespace WeiXinSDK.Common
{
	/// <summary>
	/// HTTP 客户端,默认使用json请求数据
	/// </summary>
	public static class HttpClient
	{
		static HttpClient()
		{
			Client = new System.Net.Http.HttpClient();
			Client.Timeout = TimeSpan.FromSeconds(10);
			Client.DefaultRequestHeaders.Accept.Add(
				new MediaTypeWithQualityHeaderValue("application/json"));
		}
		[ThreadStatic]
		private static System.Net.Http.HttpClient Client;

		public static async Task<string> GetStringAsync(string url)
		{
			return await Client.GetStringAsync(url);
		}

		public static async Task<string> GetStringAsync(string url, object value)
		{
			if (value == null)
			{
				return await GetStringAsync(url);
			}
			var info = value.GetType();
			var prop = info.GetProperties();
			var queryString =
				prop.Select(m => "{0}={1}".FormatExt(m.Name, (m.GetValue(value, null) ?? "").ToString().UrlEncode()))
					.JoinStr("&");
			return await Client.GetStringAsync("{0}?{1}".FormatExt(url, queryString));
		}

		/// <summary>
		/// 发起一个一部get请求,返回值使用json反序列化
		/// </summary>
		public static async Task<T> GetAsJson<T>(string url)
		{
			var str = await GetStringAsync(url);
			return str.JsonDeserialize<T>();
		}

		public static async Task<T> GetAsJson<T>(string url, object value)
		{
			var info = value.GetType();
			var prop = info.GetProperties();
			var queryString =
				prop.Select(m => "{0}={1}".FormatExt(m.Name, (m.GetValue(value, null) ?? "").ToString().UrlEncode()))
					.JoinStr("&");
			var str = await GetStringAsync("{0}?{1}".FormatExt(url, queryString));
			return str.JsonDeserialize<T>();
		}

		public static async Task<string> PostAsString(string url, string content)
		{
			var response = await Client.PostAsync(url, new StringContent(content));
			return await response.Content.ReadAsStringAsync();
		}


		public static async Task<T> PostAsJson<T>(string url, object value)
		{
			var json = await PostAsString(url, value.ToJson());
			return json.JsonDeserialize<T>();
		}

		public static async Task<string> PostFile(string url, string file)
		{
			if (!File.Exists(file))
			{
				throw new FileNotFoundException();
			}
			var fileContent = new ByteArrayContent(File.ReadAllBytes(file));
			fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
			{
				FileName = Path.GetFileName(file)
			};
			var response = await Client.PostAsync(url, fileContent);
			return await response.Content.ReadAsStringAsync();
		}

		public static async Task<HttpResponseMessage> GetResponse(string url)
		{
			return await Client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url));
		}

	}
}
